`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/01/05 14:29:57
// Design Name: 
// Module Name: data_cpkg
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module data_cpkg

(
	input					sys_clk_i,
	input 					sys_rst_i,
	
	input 			[15:0]	ddc0_data,
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)	input 					ddc0_valid,
	(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)input                    GNSS_pps,
	(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)input                    PPS_local_IN,
	
	output 	 		reg[63:0]	pkg_data,
	output 	 		reg[63:0]	pkg_data_copy,
	(*mark_debug = "true"*)output 	 				pkg_valid,
    output          reg[64-1:0]data_pps
);
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg i_pps_d1,i_pps_d2,i_pps_d3;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg GNSS_pps_d1,GNSS_pps_d2,GNSS_pps_d3;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg ch0_valid_d1;
reg 			[63:0]	ch0_data;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)wire 					ch0_valid;

(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg[23:0] ClkCnt;//655980
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg [3:0]  m_clk_state;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg[23:0] GNSS_ClkCnt;//655980
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg [3:0]  GNSS_m_clk_state;
always @(posedge sys_clk_i) 
begin
    if (sys_rst_i) begin 
		ClkCnt<=0; m_clk_state<=0;
		i_pps_d1	<= 1'b0;
		i_pps_d2	<= 1'b0;
		i_pps_d3	<= 1'b0;
	end
	else begin
	    if(m_clk_state==0)begin
		       if(i_pps_d2==0 && i_pps_d1==1)begin  ClkCnt<=0; m_clk_state<=1;end
		    end
		if(m_clk_state==1)begin
		      ClkCnt<=ClkCnt+1;
	         if(ClkCnt==16000000)begin ClkCnt<=0;m_clk_state<=0;end
	    end
	end
    i_pps_d1<=PPS_local_IN;
    i_pps_d2<=i_pps_d1;
    i_pps_d3<=i_pps_d2;
end

always @(posedge sys_clk_i) 
begin
    if (sys_rst_i) begin 
		GNSS_ClkCnt<=0; GNSS_m_clk_state<=0;
		GNSS_pps_d1	<= 1'b0;
		GNSS_pps_d2	<= 1'b0;
		GNSS_pps_d3	<= 1'b0;
	end
	else begin
	    if(GNSS_m_clk_state==0)begin
		       if(GNSS_pps_d2==0 && GNSS_pps_d1==1)begin  GNSS_ClkCnt<=0; GNSS_m_clk_state<=1;end
		    end
		if(GNSS_m_clk_state==1)begin
		      GNSS_ClkCnt<=GNSS_ClkCnt+1;
	         if(GNSS_ClkCnt==16000000)begin GNSS_ClkCnt<=0;GNSS_m_clk_state<=0;end
	    end
	end
    GNSS_pps_d1<=GNSS_pps;
    GNSS_pps_d2<=GNSS_pps_d1;
    GNSS_pps_d3<=GNSS_pps_d2;
end

// (*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)wire [7:0] m_pkg_data;
// assign m_pkg_data = pkg_data[63:63-7];
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg [3:0]  m_pps_state;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *)reg [3:0]  GNSS_m_pps_state;
reg [1:0] pkg_cnt_inner;
reg [1:0] GNSS_pkg_cnt_inner;
always @(posedge sys_clk_i) 
begin
  if (sys_rst_i) m_pps_state<=0;
  else begin
    pkg_data<=ch0_data;
    if(m_pps_state==0)begin
		if(i_pps_d2==0 && i_pps_d1==1 && ClkCnt==0)begin
			if(ch0_valid == 1)begin
				data_pps <= ch0_data;
				pkg_data<={60'hEB905A5A5A5A146, 4'h4};
				m_pps_state<=0;				
				end
			else
				m_pps_state<=1;
		end	
	end
	if(m_pps_state==1)begin
		if(ch0_valid == 1)begin
			data_pps <= ch0_data;
			if (pkg_cnt_inner==2'd0) begin
				pkg_data<={60'hEB905A5A5A5A146, 4'h4};
			end
			else begin
				pkg_data<={60'hEB905A5A5A5A146, 2'b00, pkg_cnt_inner};
			end
			m_pps_state<=0;				
		end
	end
  end
end
// GNSS
always @(posedge sys_clk_i) 
begin
  if (sys_rst_i) GNSS_m_pps_state<=0;
  else begin
    pkg_data_copy<=ch0_data;
    if(GNSS_m_pps_state==0)begin
		if(GNSS_pps_d2==0 && GNSS_pps_d1==1 && GNSS_ClkCnt==0)begin
			if(ch0_valid == 1)begin
				pkg_data_copy<={60'hEB905A5A5A5A146, 4'h4};
				GNSS_m_pps_state<=0;				
				end
			else
				GNSS_m_pps_state<=1;
		end	
	end
	if(GNSS_m_pps_state==1)begin
		if(ch0_valid == 1)begin
			if (GNSS_pkg_cnt_inner==2'd0) begin
				pkg_data_copy<={60'hEB905A5A5A5A146, 4'h4};
			end
			else begin
				pkg_data_copy<={60'hEB905A5A5A5A146, 2'b00, GNSS_pkg_cnt_inner};
			end
			GNSS_m_pps_state<=0;				
		end
	end
  end
end


always@(posedge sys_clk_i) 
begin
	ch0_valid_d1<=ch0_valid;
end


assign  pkg_valid = ch0_valid_d1;
reg     [1:0]     m_ch0_tog; 
//(*mark_debug = "true"*) (* KEEP = "TRUE" *)reg     [3:0]     m_ddc0_valid_r;

reg     [1:0]     ch0_tog; 
reg     [3:0]     ddc0_valid_r;

always @(posedge sys_clk_i) 
begin
    m_ch0_tog<=ch0_tog;
end
always @(posedge sys_clk_i) 
begin
	if (sys_rst_i) begin
		ch0_tog  <= 'd0;
		ch0_data <= 'd0;
	end else if(ddc0_valid)begin		
		ch0_data[63:48]  <= ddc0_data;
		ch0_data[47:32]  <= ch0_data[63:48];
		ch0_data[31:16]  <= ch0_data[47:32];
		ch0_data[15:00]  <= ch0_data[31:16];
		ch0_tog <= ch0_tog + 1;	
	end
end

assign  ch0_valid = (ch0_tog==2'b00) ? ddc0_valid : 1'b0;

//always @(posedge sys_clk_i) 
//begin
//	if (sys_rst_i) begin
//		ddc0_valid_r <= 'd0;
//		ch0_valid <= 1'b0;
//	end else begin		
//		ddc0_valid_r <= {ddc0_valid_r[3:1],ddc0_valid};
//		ch0_valid <= (ch0_tog==2'b00) ? ddc0_valid : 1'b0;
//	end
//end


always @(posedge sys_clk_i or posedge sys_rst_i) begin
	if (sys_rst_i) begin
		// reset
		pkg_cnt_inner	<= 2'd0;
	end
	else if (m_pps_state==0 && i_pps_d2==0 && i_pps_d1==1 && ClkCnt==0) begin
		pkg_cnt_inner	<= ch0_tog;
	end
	else begin
		pkg_cnt_inner	<= pkg_cnt_inner;
	end
end

always @(posedge sys_clk_i or posedge sys_rst_i) begin
	if (sys_rst_i) begin
		// reset
		GNSS_pkg_cnt_inner	<= 2'd0;
	end
	else if (GNSS_m_pps_state==0 && GNSS_pps_d2==0 && GNSS_pps_d1==1 && GNSS_ClkCnt==0) begin
		GNSS_pkg_cnt_inner	<= ch0_tog;
	end
	else begin
		GNSS_pkg_cnt_inner	<= GNSS_pkg_cnt_inner;
	end
end

endmodule
